/*
 * @Author       : LuHeQiu
 * @Date         : 2023-04-19 23:08:45
 * @LastEditTime : 2023-04-21 13:53:33
 * @LastEditors  : LuHeQiu
 * @Description  : 按键库v1.0
 *                 这是一个事件驱动的多按键库，采用扫描与响应分离设计。
 *                 按键扫描函数为Key_Scan() 按键响应函数为Key_Exec() ，之间采用事件标志联系。
 *                 当Key_Scan和Key_Exec在同一个任务的上下文中时为同步按键响应。
 *                 当Key_Scan和Key_Exec在不同任务的上下文中时为异步按键响应。
 *                 后续开发进度：补充 条件编译的 宏定义，用于设置 允许长按、允许连击、最大连击次数、指定事件屏蔽 等功能。
 * @FilePath     : /UnionLink-Ctrl/Hardware/key.h
 * @HomePage     : https://www.luheqiu.com
 */
#ifndef __KEY_H
#define __KEY_H

#include "main.h"
#include "task.h"

/* 系统配置---------------------------------------------------------------- */

/* 变量类型与所需的函数接口配置 */
typedef uint8_t  Key8BitsType;
typedef uint16_t  Key16BitsType;

/* 按键声明 */
typedef struct Key Key;

extern Key* key;

/* 按键有效操作的最短时间，也可以称为消抖系数，单位：tick（KEY_SCAN函数的调用周期） */
#define KEY_VALID_MIN_TIME (2)

/* 按键长按的判别时间，单位：tick */
#define KEY_LONG_PRESSED_TIME (150)

/* 按键长按的重复报告时间，单位：tick */
#define KEY_LONG_PRESSED_REPEAT_TIME (50)

/* 按键双击/多次点击的的最大间隔，单位：tick */
#define KEY_MULTICLICK_INTERVAL_TIME (40)

/* 类型定义---------------------------------------------------------------- */

typedef enum
{
    KEY_EVENT_NONE                 =  0U,
    KEY_EVENT_PRESSED              =  1U,
    KEY_EVENT_RELEASED             =  2U,
    KEY_EVENT_MULTI_CLICKED        =  4U,
    KEY_EVENT_LONG_PRESSED         =  8U,
    KEY_EVENT_LONG_PRESSED_REPEAT  = 16U,
    KEY_EVENT_LONG_PRESSED_OVER    = 32U
}KeyEvent;


typedef struct Key
{
    void (*Callback_Handler)(KeyEvent e);
    Key16BitsType (*getClickCount)(Key* key);
    /* data */
}Key;

/* 按键声明---------------------------------------------------------------- */
extern Key *key1, *key2;



/* 函数声明---------------------------------------------------------------- */

static Key16BitsType getClickCount(Key* key);


#define Key_CheckEvent(e,EVENT) ((e)&(EVENT))


extern TaskStateShift Key_ScanLoopTask(TaskCallState state);

extern void Key_Scan(void);
extern void Key_Exec(void);






#endif
